﻿Public Class Entity

    Property PlayerParameter As PlayerParameter
    Property Zones As New ZoneCollection
    Property Countries As New CountryCollection
    Property AI As AI
    Property Flags As Flags
    Property GamePlaySetting As GamePlaySetting

    Public Sub New()

    End Sub

    Public Sub Load(filePath As String)

        Contracts.Contract.Requires(Of IO.FileNotFoundException)(IO.File.Exists(filePath))

        Dim stream As New IO.StreamReader(filePath)

        PlayerParameter = New PlayerParameter()

        Debug.Print("-------------------------------------------------------")

        Load(stream)

        Debug.Print(String.Format("{0} Line Read", ReadedLineCount))
        Debug.Print(String.Format("{0} Unmanaged Lines", UnmanagedLineCount))
        Debug.Print(String.Format("{0} Skiped Lines", SkipedLineCount))
        Debug.Print(String.Format("{0} Skiped Block", SkipedBlockCount))
        Debug.Print(String.Format("{0} Lines left to Complete full Loading", SkipedLineCount + UnmanagedLineCount))

    End Sub

    Private Sub Load(ByRef stream As IO.StreamReader)

        Dim shouldExit As Boolean = False
        Dim linedata As LineData
        Dim keyValue As KeyValueData

        Do Until shouldExit OrElse stream.EndOfStream

            linedata = ReadLineData(stream)

            Select Case linedata.LineType
                Case DataLineType.StartBlock
                    Select Case linedata.BlockName
                        Case "ai"
                            AI = New AI
                            AI.Load(stream)
                        Case "flags"
                            Flags = New Flags
                            Flags.Load(stream)
                        Case "gameplaysettings"
                            GamePlaySetting = New GamePlaySetting
                            GamePlaySetting.Load(stream)
                        Case "1"
                            Dim zone As New Zone
                            zone.Load(stream, linedata.BlockName)
                            Zones.Add(zone)

                        Case Else
                            SkipBlock(stream, linedata.BlockName)
                    End Select

                Case DataLineType.KeyValue
                    keyValue = linedata.KeyValueData
                    Select Case keyValue.Key
                        Case "date"
                            PlayerParameter.GameDate = keyValue.Value.ToDate
                        Case "player"
                            PlayerParameter.Country = keyValue.Value.ToCountry

                        Case "automate_trade"
                            PlayerParameter.AutomateTrade = keyValue.Value.ToBoolean
                        Case "automate_sliders"
                            PlayerParameter.AutomateSliders = keyValue.Value.ToInteger
                        Case "automate_tech_sliders"
                            PlayerParameter.AutomateTechSliders = keyValue.Value.ToInteger
                        Case "rebel"
                            PlayerParameter.Rebel = keyValue.Value.ToInteger
                        Case "convoy"
                            PlayerParameter.Convoy = keyValue.Value.ToInteger
                        Case "theatre"
                            PlayerParameter.Theatre = keyValue.Value.ToInteger
                        Case "unit"
                            PlayerParameter.Unit = keyValue.Value.ToInteger
                        Case "victory_conditions"
                            ' todo read block
                        Case "seed"
                            PlayerParameter.Seed = keyValue.Value.ToInteger
                        Case "count"
                            PlayerParameter.Count = keyValue.Value.ToInteger
                        Case "id"
                            ' todo read block
                        Case "fired_events"
                            ' todo read block

                        Case Else
                            If keyValue IsNot Nothing AndAlso Country.IsCountry(keyValue.Value.Text) Then
                                Dim country As New Country
                                country.Load(stream, CountryConverter(keyValue.Value.Text))
                                Countries.Add(country)
                            Else
                                AddUnmanagedLine(linedata.OriginalText)
                            End If
                    End Select

                Case DataLineType.StarBlockChar, DataLineType.EndBlockChar
                    'nothing to do

                Case Else
                    AddUnmanagedLine(linedata.OriginalText)
            End Select

        Loop

    End Sub

End Class


Public Enum DataLineType
    KeyValue
    InLine
    StartBlock
    StarBlockChar
    EndBlockChar
End Enum

Public Class LineData

    Public Property LineType As DataLineType
    Public Property InLineData As InlineData
    Public Property KeyValueData As KeyValueData
    Public Property OriginalText As String
    Public Property BlockName As String

    Sub New()

    End Sub

    Friend Sub New(data As InlineData, originalText As String)

        LineType = DataLineType.InLine
        InLineData = data

    End Sub

    Friend Sub New(data As KeyValueData, originalText As String)

        LineType = DataLineType.KeyValue
        KeyValueData = data

    End Sub

    Friend Sub New(blockName As String, originalText As String)

        LineType = DataLineType.StartBlock
        Me.BlockName = blockName

    End Sub

End Class

Public Class InlineData

    Public Property WithEndOfBlock As Boolean
    Public Property Values As List(Of String)

    Sub New()

        Values = New List(Of String)
        WithEndOfBlock = False

    End Sub

    Sub New(value As List(Of String))

        Me.new(value, False)

    End Sub

    Sub New(value As List(Of String), endOfBlock As Boolean)

        Values = value
        WithEndOfBlock = endOfBlock

    End Sub

End Class

Public Class Value

    Property Text As String

    Sub New(text As String)
        Me.Text = text
    End Sub

    public Function ToInteger() As Integer
        Return Integer.Parse(Text)
    End Function

    Public Function ToDecimal() As Decimal
        Return Decimal.Parse(Text, Globalization.CultureInfo.InvariantCulture)
    End Function

    Public Function ToDate() As Date
        Return Date.Parse(DateConverter(Text))
    End Function

    Public Function ToBoolean() As Boolean
        Return ConvertBoolean(Text)
    End Function

    Public Function ToCountry() As CountryShortName
        Return CountryConverter(Text)
    End Function

End Class

Public Class KeyValueData

    Public Property Key As String
    Public Property Value As Value

    Public Sub New()
        Value = New Value(String.Empty)
    End Sub

    Public Sub New(key As String, value As String)
        Me.Key = key
        Me.Value = New Value(value)
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean

        Dim result As Boolean

        If obj Is GetType(KeyValueData) Then
            result = Equals(obj)
        Else
            result = False
        End If

        Return result

    End Function

    Public Overloads Function Equals(obj As KeyValueData) As Boolean

        Dim result As Boolean

        If Key.Equals(obj.Key) AndAlso Value.Equals(obj.Value) Then
            result = True
        Else
            result = False
        End If

        Return result

    End Function

End Class